from django_restql.fields import DynamicSerializerMethodField
from django_restql.mixins import DynamicFieldsMixin
from rest_framework.serializers import ModelSerializer, ListSerializer, Serializer

from rest_framework.fields import empty
from rest_framework.request import Request

from utils.validator import CustomValidationError


class RewriteDynamicFieldsMixin(DynamicFieldsMixin):
    @staticmethod
    def is_field_found(field_name, all_field_names, raise_exception=False):
        if field_name in all_field_names:
            return True
        else:
            if raise_exception:
                msg = "%s 字段未找到" % field_name
                raise CustomValidationError(msg)
            return False

    @staticmethod
    def is_nested_field(field_name, field, raise_exception=False):
        nested_classes = (
            Serializer, ListSerializer,
            DynamicSerializerMethodField
        )
        if isinstance(field, nested_classes):
            return True
        else:
            if raise_exception:
                msg = "%s 嵌套字段未找到" % field_name
                raise CustomValidationError(msg)
            return False


class RewriteModelSerializer(ModelSerializer):

    creator_field_id = 'user'
    modifier_field_id = "user"

    def __init__(self, instance=None, data=empty, request=None, **kwargs):
        super().__init__(instance, data, **kwargs)
        self.request: Request = request or self.context.get("request", None)

    def create(self, validated_data):
        if self.request:
            if str(self.request.user) != "AnonymousUser":
                if self.creator_field_id in self.fields.fields:
                    validated_data[self.creator_field_id] = self.request.user

        return super().create(validated_data)

    def update(self, instance, validated_data):
        if self.request:
            if str(self.request.user) != "AnonymousUser":
                if self.modifier_field_id in self.fields.fields:
                    validated_data[self.modifier_field_id] = self.request.user
            # if hasattr(self.instance, self.modifier_field_id):
            #     setattr(
            #         self.instance, self.modifier_field_id, self.get_request_user_id()
            #     )
        return super().update(instance, validated_data)

    def get_request_user_id(self):
        if getattr(self.request, "user", None):
            return getattr(self.request.user, "id", None)
        return None

    @property
    def errors(self):
        # get errors
        errors = super().errors
        verbose_errors = {}
        # fields = { field.name: field.verbose_name } for each field in model
        fields = {field.name: field.verbose_name for field in
                  self.Meta.model._meta.get_fields() if hasattr(field, 'verbose_name')}
        # iterate over errors and replace error key with verbose name if exists
        for field_name, error in errors.items():
            if field_name in fields:
                verbose_errors[str(fields[field_name])] = error
            else:
                verbose_errors[field_name] = error
        return verbose_errors


class CustomModelSerializer(RewriteDynamicFieldsMixin, RewriteModelSerializer):

    pass


